export interface ThrottleOptions {
    wait?: number;
    leading?: boolean;
    trailing?: boolean;
}

export interface Result {
    run: (...args: any[]) => Promise<any>,
    cancel: () => void
}

/**
 * @param {*} fn 要执行的函数
 * @param {*} options 可选参数： wait时间间隔，leading第一次是否执行, trailing 最后一次是否执行
 * @returns run、cancel
 */
export function useThrottle(
    fn: () => unknown,
    options: ThrottleOptions = { leading: true, trailing: false }
): Result {

    // 1.记录上一次的开始时间
    const { leading, trailing, wait } = options
    let lastTime = 0
    let timer: any = null
   
    // 2.事件触发时, 真正执行的函数
    const throttle = function (...args: any) {
      return new Promise((resolve, reject) => { //promise方式返回返回值
        // 2.1.获取当前事件触发时的时间
        const nowTime = new Date().getTime()
        if (!lastTime && !leading) lastTime = nowTime
   
        // 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数
        const remainTime = (wait || 0) - (nowTime - lastTime)
        if (remainTime <= 0) {
          if (timer) {
            clearTimeout(timer)
            timer = null
          }
   
          // 2.3.真正触发函数
          const result = fn.apply(this, args)
          resolve(result)
          // 2.4.保留上次触发的时间
          lastTime = nowTime
          return
        }
   
        if (trailing && !timer) {
          timer = setTimeout(() => {
            const result = fn.apply(this, args as any)
            resolve(result)
            timer = null
            lastTime = !leading ? 0 : new Date().getTime()
          }, remainTime)
        }
      })
    }
   
    const cancel = function () {
      if (timer) clearTimeout(timer)
      timer = null
      lastTime = 0
    }
   
    return {
        run: throttle,
        cancel: cancel
    }
}